package de.jonasjelten.jcalc.math;

import de.jonasjelten.jcalc.exception.JMathematicalException;
import java.math.BigInteger;

/**
 * Diese klasse berechnet einen Fakultätsabschnitt um die gesamtberechnung auf
 * mehrere Kerne zu verteilen.
 * @author Jonas Jelten
 */
public class JNumberFacultyHelperThread extends Thread {

    private BigInteger result;
    private BigInteger low, high;

    public JNumberFacultyHelperThread(BigInteger lowLimit, BigInteger highLimit) throws JMathematicalException {
        super("Faculty-Thread:" + lowLimit + "->" + highLimit);
        low = lowLimit;
        high = highLimit;
        if (low.compareTo(BigInteger.ZERO) <= 0 || high.compareTo(BigInteger.ZERO) <= 0 || low.compareTo(high) > 0) {
            throw new JMathematicalException("Bounds in faculty thread are set wrong. They may be < 0 or lowlimit is bigger than highlimit.");
        }
    }

    /**
     * Thread zum berechnen eines Fakultätsabschnitts
     * was bedeutet:   highLimit!/lowLimit!
     */
    @Override
    public void run() {
        //System.out.println("INIT:low:" + low + ",high:" + high);
        if (low.compareTo(high) == 0) {
            result = low;
        } else {
            result = BigInteger.ONE;
            for (BigInteger i = low; i.compareTo(high) <= 0; i = i.add(BigInteger.ONE)) {
                //System.out.println("multi:result="+result+"*"+i);
                result = i.compareTo(BigInteger.ZERO) == 0 ? result.multiply(i) : result;
            }
        }
    }

    /**
     * Liefert das Rechenergebnis dieser Fakultät
     *
     * @return das ergebnis dieses Fakultätsabschnitts
     */
    public BigInteger getResult() {
        try {
            this.join();
        } catch (InterruptedException ex) {
            System.out.println(ex.toString());
        }
        return result;
    }
}
